package dao

import (
	"encoding/json"
	"fmt"
	"math"
	"strings"
	"time"
	"user_srv/handler/model"
)

// SoulMatchingService 灵魂匹配服务
// 基于深度问答进行用户匹配
// 通过分析用户在问题上的答案来评估兼容性
type SoulMatchingService struct{}

// NewSoulMatchingService 创建灵魂匹配服务实例
func NewSoulMatchingService() *SoulMatchingService {
	return &SoulMatchingService{}
}

// GetSoulQuestions 获取灵魂问答题目
// 功能：获取用于灵魂匹配的问答题目
// 题目特点：
//   - 涵盖不同分类（性格、价值观、生活方式等）
//   - 支持单选或多选
//   - 每道题有权重（重要程度不同）
//
// 参数：
//   - userID: 用户ID
//   - category: 题目分类（可选）
//   - limit: 题目数量限制
//
// 返回值：题目列表
func (s *SoulMatchingService) GetSoulQuestions(userID int64, category string, limit int32) ([]model.XqSoulQuestions, error) {
	var questionModel model.XqSoulQuestions
	return questionModel.ListByCategory(category, int(limit))
}

// SubmitSoulAnswer 提交灵魂问答答案
// 功能：保存用户对题目的答案
// 处理流程：
//  1. 检查是否已经回答过该题（避免重复提交）
//  2. 将答案转换为JSON格式保存
//  3. 更新用户灵魂档案的完成度
//
// 参数：
//   - userID: 用户ID
//   - questionID: 题目ID
//   - answers: 答案列表（支持多选）
//   - answerScore: 答案分数
func (s *SoulMatchingService) SubmitSoulAnswer(userID, questionID int64, answers []string, answerScore float64) error {
	// 检查是否已经回答过
	var answerModel model.XqUserSoulAnswers
	if answerModel.HasAnswered(userID, questionID) {
		return fmt.Errorf("已经回答过这道题")
	}

	// 将答案转换为JSON
	answerJSON, err := json.Marshal(answers)
	if err != nil {
		return err
	}

	// 创建答案记录
	answer := model.XqUserSoulAnswers{
		UserId:      userID,
		QuestionId:  questionID,
		Answer:      string(answerJSON),
		AnswerScore: answerScore,
		AnsweredAt:  time.Now(),
	}

	err = answer.Create()
	if err != nil {
		return err
	}

	// 更新用户灵魂档案
	return s.updateUserSoulProfile(userID)
}

// GetUserSoulProfile 获取用户灵魂档案
// 功能：获取用户的灵魂匹配档案信息
// 档案信息：
//   - 完成度（已答题数/总题数）
//   - 人格类型
//   - 关系风格
//   - 最后答题时间
//
// 如果用户没有档案，会自动创建
// 参数：
//   - userID: 用户ID
func (s *SoulMatchingService) GetUserSoulProfile(userID int64) (*model.XqUserSoulProfile, error) {
	var profileModel model.XqUserSoulProfile
	profile, err := profileModel.GetByUserId(userID)
	if err != nil {
		// 如果不存在，创建新的档案
		profile = &model.XqUserSoulProfile{
			UserId:         userID,
			CompletionRate: 0.0,
		}
		err = profile.Create()
		if err != nil {
			return nil, err
		}
	}
	return profile, nil
}

// CalculateSoulCompatibility 计算灵魂契合度
// 功能：计算两个用户之间的灵魂契合度分数
// 计算逻辑：
//  1. 获取两个用户的所有答案
//  2. 计算答案相似度（共同答案数量）
//  3. 分析共同答案的详情
//  4. 生成匹配理由
//  5. 保存匹配结果到数据库
//
// 参数：
//   - userID1, userID2: 两个用户ID
//
// 返回值：
//   - CompatibilityScore: 契合度分数（0-100）
//   - CommonAnswers: 共同答案列表
//   - MatchReasons: 匹配原因
func (s *SoulMatchingService) CalculateSoulCompatibility(userID1, userID2 int64) (*SoulCompatibilityResult, error) {
	// 获取两个用户的答案
	answers1, err := s.getUserAnswers(userID1)
	if err != nil {
		return nil, err
	}

	answers2, err := s.getUserAnswers(userID2)
	if err != nil {
		return nil, err
	}

	if len(answers1) == 0 || len(answers2) == 0 {
		return nil, fmt.Errorf("用户答题数据不足")
	}

	// 计算契合度
	compatibilityScore := s.calculateCompatibilityScore(answers1, answers2)

	// 获取共同答案详情
	commonAnswers := s.getCommonAnswers(answers1, answers2)

	// 生成匹配原因
	matchReasons := s.generateMatchReasons(compatibilityScore, commonAnswers)

	result := &SoulCompatibilityResult{
		UserID1:            userID1,
		UserID2:            userID2,
		CompatibilityScore: compatibilityScore,
		CommonAnswers:      commonAnswers,
		MatchReasons:       matchReasons,
		CommonCount:        len(commonAnswers),
		TotalQuestions:     len(answers1),
	}

	// 保存匹配结果
	err = s.saveSoulMatch(result)
	if err != nil {
		return nil, err
	}

	return result, nil
}

// GetSoulMatches 获取灵魂匹配结果
// 功能：获取用户的灵魂匹配列表
// 返回信息：
//   - 匹配用户的详细信息
//   - 契合度分数
//   - 匹配时间
//
// 参数：
//   - userID: 用户ID
//   - page: 页码
//   - pageSize: 每页数量
//
// 返回值：匹配列表和总记录数
func (s *SoulMatchingService) GetSoulMatches(userID int64, page, pageSize int32) ([]SoulMatchInfo, int32, error) {
	var matchModel model.XqSoulMatches

	// 计算总数
	total, err := matchModel.CountByUserId(userID)
	if err != nil {
		return nil, 0, err
	}

	// 分页查询
	offset := int((page - 1) * pageSize)
	matches, err := matchModel.ListByUserId(userID, int(pageSize), offset)
	if err != nil {
		return nil, 0, err
	}

	// 转换为SoulMatchInfo
	var matchInfos []SoulMatchInfo
	for _, match := range matches {
		targetUserID := match.UserId2
		if match.UserId2 == userID {
			targetUserID = match.UserId1
		}

		// 获取目标用户信息
		userInfo, err := s.getUserInfo(targetUserID)
		if err != nil {
			continue
		}

		matchInfo := SoulMatchInfo{
			UserID:             targetUserID,
			Nickname:           userInfo.Nickname,
			Avatar:             userInfo.Avatar,
			Age:                userInfo.Age,
			Gender:             int32(userInfo.Gender),
			Bio:                userInfo.Bio,
			CompatibilityScore: match.CompatibilityScore,
			CreatedAt:          match.CreatedAt.Unix(),
		}

		matchInfos = append(matchInfos, matchInfo)
	}

	return matchInfos, int32(total), nil
}

// GetSoulMatchDetail 获取灵魂匹配详情
// 功能：获取与特定用户的详细灵魂匹配信息
// 详细信息：
//   - 用户基本信息（昵称、头像、年龄、性别、简介）
//   - 契合度分数
//   - 共同答案详情
//   - 匹配理由
//   - 人格类型
//
// 参数：
//   - userID: 当前用户ID
//   - targetUserID: 目标用户ID
func (s *SoulMatchingService) GetSoulMatchDetail(userID, targetUserID int64) (*SoulMatchDetail, error) {
	var matchModel model.XqSoulMatches
	match, err := matchModel.GetByUserIds(userID, targetUserID)
	if err != nil {
		return nil, fmt.Errorf("匹配记录不存在")
	}

	// 获取目标用户信息
	userInfo, err := s.getUserInfo(targetUserID)
	if err != nil {
		return nil, err
	}

	// 获取用户灵魂档案
	profile, err := s.GetUserSoulProfile(targetUserID)
	if err != nil {
		return nil, err
	}

	// 转换共同答案
	var commonAnswers []CommonAnswer
	if match.CommonAnswers != "" {
		err = json.Unmarshal([]byte(match.CommonAnswers), &commonAnswers)
		if err != nil {
			commonAnswers = []CommonAnswer{}
		}
	}

	// 转换匹配原因
	var matchReasons []string
	if match.MatchReasons != "" {
		err = json.Unmarshal([]byte(match.MatchReasons), &matchReasons)
		if err != nil {
			matchReasons = []string{}
		}
	}

	detail := &SoulMatchDetail{
		UserID:             targetUserID,
		Nickname:           userInfo.Nickname,
		Avatar:             userInfo.Avatar,
		Age:                userInfo.Age,
		Gender:             int32(userInfo.Gender),
		Bio:                userInfo.Bio,
		CompatibilityScore: match.CompatibilityScore,
		CommonAnswers:      commonAnswers,
		MatchReasons:       matchReasons,
		PersonalityType:    profile.PersonalityType,
		CreatedAt:          match.CreatedAt.Unix(),
	}

	return detail, nil
}

// 辅助方法

// getUserAnswers 获取用户答案
func (s *SoulMatchingService) getUserAnswers(userID int64) ([]model.XqUserSoulAnswers, error) {
	var answerModel model.XqUserSoulAnswers
	return answerModel.ListByUserId(userID)
}

// calculateCompatibilityScore 计算契合度分数
func (s *SoulMatchingService) calculateCompatibilityScore(answers1, answers2 []model.XqUserSoulAnswers) float64 {
	if len(answers1) == 0 || len(answers2) == 0 {
		return 0.0
	}

	// 创建答案映射
	answerMap2 := make(map[int64][]string)
	for _, answer := range answers2 {
		var answerList []string
		json.Unmarshal([]byte(answer.Answer), &answerList)
		answerMap2[answer.QuestionId] = answerList
	}

	commonCount := 0
	totalQuestions := len(answers1)

	for _, answer1 := range answers1 {
		var answerList1 []string
		json.Unmarshal([]byte(answer1.Answer), &answerList1)

		if answerList2, exists := answerMap2[answer1.QuestionId]; exists {
			if s.hasCommonAnswer(answerList1, answerList2) {
				commonCount++
			}
		}
	}

	if totalQuestions == 0 {
		return 0.0
	}

	// 计算契合度百分比
	return math.Round(float64(commonCount)/float64(totalQuestions)*100*100) / 100
}

// hasCommonAnswer 检查是否有共同答案
func (s *SoulMatchingService) hasCommonAnswer(answer1, answer2 []string) bool {
	for _, a1 := range answer1 {
		for _, a2 := range answer2 {
			if strings.EqualFold(strings.TrimSpace(a1), strings.TrimSpace(a2)) {
				return true
			}
		}
	}
	return false
}

// getCommonAnswers 获取共同答案
func (s *SoulMatchingService) getCommonAnswers(answers1, answers2 []model.XqUserSoulAnswers) []CommonAnswer {
	var commonAnswers []CommonAnswer

	// 创建答案映射
	answerMap2 := make(map[int64][]string)
	for _, answer := range answers2 {
		var answerList []string
		json.Unmarshal([]byte(answer.Answer), &answerList)
		answerMap2[answer.QuestionId] = answerList
	}

	for _, answer1 := range answers1 {
		var answerList1 []string
		json.Unmarshal([]byte(answer1.Answer), &answerList1)

		if answerList2, exists := answerMap2[answer1.QuestionId]; exists {
			commonAnswersList := s.findCommonAnswers(answerList1, answerList2)
			if len(commonAnswersList) > 0 {
				// 获取题目信息
				var questionModel model.XqSoulQuestions
				question, err := questionModel.GetById(answer1.QuestionId)
				if err != nil {
					continue
				}

				commonAnswer := CommonAnswer{
					QuestionID:    answer1.QuestionId,
					Question:      question.Question,
					CommonAnswers: commonAnswersList,
				}
				commonAnswers = append(commonAnswers, commonAnswer)
			}
		}
	}

	return commonAnswers
}

// findCommonAnswers 找出共同答案
func (s *SoulMatchingService) findCommonAnswers(answer1, answer2 []string) []string {
	var common []string

	for _, a1 := range answer1 {
		for _, a2 := range answer2 {
			if strings.EqualFold(strings.TrimSpace(a1), strings.TrimSpace(a2)) {
				common = append(common, a1)
				break
			}
		}
	}

	return common
}

// generateMatchReasons 生成匹配原因
func (s *SoulMatchingService) generateMatchReasons(score float64, commonAnswers []CommonAnswer) []string {
	var reasons []string

	if score >= 80 {
		reasons = append(reasons, "高度契合")
	} else if score >= 60 {
		reasons = append(reasons, "较为契合")
	} else if score >= 40 {
		reasons = append(reasons, "部分契合")
	} else {
		reasons = append(reasons, "有待了解")
	}

	if len(commonAnswers) > 0 {
		reasons = append(reasons, fmt.Sprintf("在%d个问题上答案一致", len(commonAnswers)))
	}

	return reasons
}

// saveSoulMatch 保存灵魂匹配结果
func (s *SoulMatchingService) saveSoulMatch(result *SoulCompatibilityResult) error {
	// 检查是否已存在匹配记录
	var matchModel model.XqSoulMatches
	existingMatch, err := matchModel.GetByUserIds(result.UserID1, result.UserID2)
	if err == nil {
		// 更新现有记录
		existingMatch.CompatibilityScore = result.CompatibilityScore
		existingMatch.UpdatedAt = time.Now()

		// 转换共同答案为JSON
		commonAnswersJSON, _ := json.Marshal(result.CommonAnswers)
		existingMatch.CommonAnswers = string(commonAnswersJSON)

		// 转换匹配原因为JSON
		matchReasonsJSON, _ := json.Marshal(result.MatchReasons)
		existingMatch.MatchReasons = string(matchReasonsJSON)

		return existingMatch.Update(model.XqSoulMatches{Id: existingMatch.Id})
	}

	// 创建新记录
	commonAnswersJSON, _ := json.Marshal(result.CommonAnswers)
	matchReasonsJSON, _ := json.Marshal(result.MatchReasons)

	match := model.XqSoulMatches{
		UserId1:            result.UserID1,
		UserId2:            result.UserID2,
		CompatibilityScore: result.CompatibilityScore,
		CommonAnswers:      string(commonAnswersJSON),
		MatchReasons:       string(matchReasonsJSON),
	}

	return match.Create()
}

// updateUserSoulProfile 更新用户灵魂档案
func (s *SoulMatchingService) updateUserSoulProfile(userID int64) error {
	// 获取用户答题统计
	var answerModel model.XqUserSoulAnswers
	answers, err := answerModel.ListByUserId(userID)
	if err != nil {
		return err
	}

	// 获取总题目数
	var questionModel model.XqSoulQuestions
	questions, err := questionModel.List(model.XqSoulQuestions{IsActive: 1})
	if err != nil {
		return err
	}

	completionRate := 0.0
	if len(questions) > 0 {
		completionRate = float64(len(answers)) / float64(len(questions)) * 100
	}

	// 更新或创建灵魂档案
	profile := model.XqUserSoulProfile{
		UserId:         userID,
		CompletionRate: completionRate,
		LastAnsweredAt: time.Now(),
	}

	return profile.CreateOrUpdate(profile)
}

// getUserInfo 获取用户信息
func (s *SoulMatchingService) getUserInfo(userID int64) (*model.XqUserProfiles, error) {
	var profileModel model.XqUserProfiles
	profile, err := profileModel.GetByUserId(userID)
	if err != nil {
		return nil, err
	}
	return profile, nil
}

// SoulCompatibilityResult 灵魂契合度结果结构体
// 存储两个用户之间的灵魂匹配分析结果
// - UserID1, UserID2: 两个用户ID
// - CompatibilityScore: 契合度分数（0-100）
// - CommonAnswers: 共同答案列表
// - MatchReasons: 匹配原因说明
// - CommonCount: 共同答案数量
// - TotalQuestions: 总题目数
type SoulCompatibilityResult struct {
	UserID1            int64          `json:"user_id_1"`
	UserID2            int64          `json:"user_id_2"`
	CompatibilityScore float64        `json:"compatibility_score"`
	CommonAnswers      []CommonAnswer `json:"common_answers"`
	MatchReasons       []string       `json:"match_reasons"`
	CommonCount        int            `json:"common_count"`
	TotalQuestions     int            `json:"total_questions"`
}

// SoulMatchInfo 灵魂匹配信息结构体
// 用于返回灵魂匹配用户的基本信息
// - UserID: 用户ID
// - Nickname: 昵称
// - Avatar: 头像
// - Age: 年龄
// - Gender: 性别
// - Bio: 简介
// - CompatibilityScore: 契合度分数
// - CreatedAt: 匹配时间（Unix时间戳）
type SoulMatchInfo struct {
	UserID             int64   `json:"user_id"`
	Nickname           string  `json:"nickname"`
	Avatar             string  `json:"avatar"`
	Age                int32   `json:"age"`
	Gender             int32   `json:"gender"`
	Bio                string  `json:"bio"`
	CompatibilityScore float64 `json:"compatibility_score"`
	CreatedAt          int64   `json:"created_at"`
}

// SoulMatchDetail 灵魂匹配详情结构体
// 用于返回详细的灵魂匹配信息
// - UserID: 用户ID
// - Nickname: 昵称
// - Avatar: 头像
// - Age: 年龄
// - Gender: 性别
// - Bio: 简介
// - CompatibilityScore: 契合度分数
// - CommonAnswers: 共同答案详情
// - MatchReasons: 匹配原因
// - PersonalityType: 人格类型
// - CreatedAt: 匹配时间（Unix时间戳）
type SoulMatchDetail struct {
	UserID             int64          `json:"user_id"`
	Nickname           string         `json:"nickname"`
	Avatar             string         `json:"avatar"`
	Age                int32          `json:"age"`
	Gender             int32          `json:"gender"`
	Bio                string         `json:"bio"`
	CompatibilityScore float64        `json:"compatibility_score"`
	CommonAnswers      []CommonAnswer `json:"common_answers"`
	MatchReasons       []string       `json:"match_reasons"`
	PersonalityType    string         `json:"personality_type"`
	CreatedAt          int64          `json:"created_at"`
}

// CommonAnswer 共同答案结构体
// 用于返回两个用户都选择的答案信息
// - QuestionID: 题目ID
// - Question: 题目内容
// - CommonAnswers: 共同答案列表（双方都选择的内容）
type CommonAnswer struct {
	QuestionID    int64    `json:"question_id"`
	Question      string   `json:"question"`
	CommonAnswers []string `json:"common_answers"`
}
